home *** CD-ROM | disk | FTP | other *** search
/ Spanish Scene 1 / SpanishScene1.iso / spanish pack n°1 by llfb / --llfb-- / programas / sources1.dms / sources1.adf / SOURCES / Disco / GetDrive.ASM < prev    next >
Assembly Source File  |  1996-06-04  |  13KB  |  368 lines

  1.  
  2. ** NOTA de ROMAN SOFT/LLFB: Este source requiere los Includes. Búscate un
  3. ** disco con ellos y edita el INCDIR poniendo el path completo. Sorry!
  4.  
  5.  
  6.  
  7. **    opt    o+,ow-            ;Devpac 2.0 options
  8.  
  9. ; Before we go to the main subject, I'll give some special information about
  10. ; macros in Devpac 2.0.
  11. ;
  12. ; It is possible to pass a size  (byte, word, long) to macros.  This is done
  13. ; with \0 (the SIZE parameter).  If ".b" or ".w" or ".l" is added just after
  14. ; the macro name in the macro call then \0 will result in "b" or "w" or "l".
  15. ; When no size is given \0 will default to "w".
  16. ;
  17. ; If you want  to pass a  parameter  that  contains spaces  then enclose the
  18. ; parameter in the macro call between these brackets: <>.
  19. ;
  20. ; Now we go to the main event...
  21. ;
  22. ;---------------------------------------------------------------------------
  23. ;
  24. ; Dr. Maybe presents...      >>>> GETDRIVE routine <<<<
  25. ;
  26. ; I would like to talk about a common problem in programs that write to disk
  27. ; at low level (i.e. at bitmap  level).  For  example  a  simple fast-format
  28. ; (initialize) function  or installing  an intro or picture in the first few
  29. ; tracks of a disk.
  30. ;
  31. ; What happens? Mostly the bitmap structure of the disk is  changed. In case
  32. ; of initializing  a new Root and Bitmap block are written, and in case of a
  33. ; bootintro the Bitmap block is changed in such a way that a  few tracks are
  34. ; allocated for  the intro.  In both  cases the  information on the disk has
  35. ; changed.
  36. ;
  37. ; But AmigaDOS  must be  informed about  this. Otherwise  AmigaDOS will give
  38. ; wrong information  about the  disk. After initializing the disk will still
  39. ; be full or not  validated. After  a bootintro  is installed  too much free
  40. ; disk space  will be showed. The only way to update the disk information is
  41. ; to eject and insert it. Another danger is  when other  tasks want  to have
  42. ; access to the disk, while your program is writing to the tracks!
  43. ;
  44. ; I hope  the problem  is clear.  The program must reserve the drive for own
  45. ; use, without permitting other tasks to have access  to it,  and afterwards
  46. ; the drive  must be  returned to system. Well, that's not so difficult, you
  47. ; might think, lets look it up in the books. I sought and sought, but didn't
  48. ; find. And I think most other Amiga programmers have the same problem. Take
  49. ; for example "Bootleg" or "Bootgirl" or "Bootem". Only the Workbench Format
  50. ; command does drive-handling nicely. You even get a "DF1:BUSY" icon.
  51. ;
  52. ; So,  what's  the  only  thing  left  to  do for an Amiga freak? Right, you
  53. ; guessed it, I disassembled the Format command! Here comes the solution.
  54. ;
  55. ;---------------------------------------------------------------------------
  56. ;
  57. ; First find the task that's responsible  for giving  other tasks  access to
  58. ; the drive. This is done with the following function from dos.library:
  59. ;
  60. ;    Process_MessagePort = DeviceProc( name )
  61. ;        d0                             d1
  62. ;
  63. ; Here  d1  points  to  the  name  of  the drive (e.g. 'DF1:',0), which is a
  64. ; NULL-terminated string. The returned value in d0 is the MessagePort of the
  65. ; DOS process  that's controlling  the drive.  A DOS process is just an exec
  66. ; task added with a MessagePort (so  we  can  talk  with  it)  and  some DOS
  67. ; information (like  CLI, Filesystem,  etc). All programs loaded from CLI or
  68. ; Workbench    are    DOS    processes.     Lets    take     a    look    at
  69. ; "include/libraries/dosextens.i": 
  70. ;
  71. ; STRUCTURE Process,0
  72. ;    STRUCT  pr_Task,TC_SIZE     * APTR to exec task
  73. ;    STRUCT  pr_MsgPort,MP_SIZE  * This is BPTR address from DOS functions
  74. ;    WORD    pr_Pad              * Remaining variables on 4 byte boundaries
  75. ;    BPTR    pr_SegList          * Array of seg lists used by this process
  76. ;    (etc)
  77. ;---------------------------------------------------------------------------
  78. ;
  79. ; Now we  send a StandardPacket to the process. A standard packet is just an
  80. ; exec message added with  some  extras,  called  DOS  packet.  These extras
  81. ; consist of  our ReplyPort (to get messages back) and information about the
  82. ; command we would like  to  give  to  the  process.  Lets  take  a  look at
  83. ; "include/libraries/dosextens.i":
  84. ;
  85. ; STRUCTURE StandardPacket,0
  86. ;   STRUCT sp_Msg,MN_SIZE       * message
  87. ;   STRUCT sp_Pkt,dp_SIZEOF     * DOS packet
  88. ;   LABEL  sp_SIZEOF
  89. ;
  90. ; STRUCTURE DosPacket,0
  91. ;   APTR   dp_Link         * pointer to EXEC message
  92. ;   APTR   dp_Port         * pointer to Reply port for the packet
  93. ;                          * Must be filled in each send.
  94. ;   LONG   dp_Type         * See ACTION_... below and
  95. ;                          * 'R' means Read, 'W' means Write to the file system
  96. ;   LONG   dp_Res1         * For file system calls this is the result
  97. ;                          * that would have been returned by the
  98. ;                          * function, e.g. Write ('W') returns actual
  99. ;                          * length written
  100. ;   LONG   dp_Res2         * For file system calls this is what would
  101. ;                          * have been returned by IoErr()
  102. ;   LONG   dp_Arg1
  103. ;   (etc)
  104. ;
  105. ; ACTION_INHIBIT          EQU     31
  106. ;   (etc)
  107. ;
  108. ; The most important element here is  dp_Type. This  element is  filled with
  109. ; the command we want to give: ACTION_INHIBIT. For drive reservation we make
  110. ; dp_Arg1 = 1 and to return the drive to system we make dp_Arg1 =  0. We can
  111. ; do many  things with  packets. Look at the complete include file yourself!
  112. ; After setting up the packet properly, we send it to the process  port with
  113. ; the  exec  function  PutMsg.  Then  we  GetMsg from drive process back and
  114. ; Remove the packet and check error in dp_Res1.
  115. ;
  116. ;---------------------------------------------------------------------------
  117. ;
  118. ; Of course you did't understand anything  of this  bulls..t mambo  jambo (I
  119. ; kneuw that!),  but it works perfectly. Even the "DF0:BUSY" icon appears in
  120. ; Workbench!! For full details look at the GetDrive routine below.
  121. ;
  122. ; GOOD LUCK!
  123. ;
  124. ; Dr. Maybe
  125. ; Postbus 121
  126. ; 6850 AD Huissen
  127. ; Holland
  128. ;
  129. ;---------------------------------------------------------------------------
  130.  
  131.     incdir    "ram:include/"        ;your include directory
  132.     include    "exec/exec_lib.i"
  133.     include    "exec/memory.i"
  134.     include    "exec/ports.i"
  135.     include    "libraries/dos_lib.i"
  136.     include    "libraries/dosextens.i"
  137.  
  138.  
  139. CALL    MACRO                ;library function call
  140.     jsr    _LVO\1(a6)
  141.     ENDM
  142.  
  143.  
  144.     SECTION    main,CODE
  145.  
  146. ;**** Open DOS ****
  147.     lea    _DOSName(pc),a1
  148.     moveq    #0,d0
  149.     CALLEXEC OpenLibrary
  150.     move.l    d0,_DOSBase
  151.     beq    quit
  152.  
  153. ;**** Open RAW Window, so I can talk to you. ****
  154.     lea    rawwindowname(pc),a0
  155.     move.l    a0,d1
  156.     move.l    #MODE_OLDFILE,d2
  157.     CALLDOS    Open
  158.     move.l    d0,rawwindow
  159.     beq    quit
  160.  
  161. ;**** Now get drive for own use. ****
  162.     lea    drivename(pc),a0
  163.     moveq    #1,d0
  164.     bsr    GetDrive
  165.     beq.s    ok
  166.  
  167. ;**** check & display error, and quit ****
  168.     lea    not_mounted(pc),a0
  169.     cmp.b    #218,d0
  170.     beq.s    prt
  171.     lea    doserror(pc),a0
  172.     cmp.b    #100,d0
  173.     beq.s    prt
  174.     lea    drive_in_use(pc),a0
  175. prt
  176.     bsr    print
  177.     bsr    wait_key
  178.     bra.s    quit
  179.  
  180. ok
  181. ;**** drive disabled successfully ****
  182.     lea    drive_disabled(pc),a0
  183.     bsr    print
  184.     bsr    wait_key
  185.  
  186. ;**** return drive to system
  187.     lea    drivename(pc),a0
  188.     moveq    #0,d0
  189.     bsr    GetDrive
  190.  
  191. quit
  192. ;**** cleanup & exit ****
  193.     move.l    rawwindow(pc),d1    ;close raw window
  194.     beq.s    .q1
  195.     CALLDOS    Close
  196. .q1
  197.     move.l    _DOSBase(pc),d0        ;close DOS
  198.     beq.s    .q2
  199.     move.l    d0,a1
  200.     CALLEXEC CloseLibrary
  201. .q2
  202.     moveq    #0,d0
  203.     rts
  204.  
  205. print
  206. ;**** output text in a0 to rawwindow, and wait ****
  207.     move.l    rawwindow(pc),d1
  208.     move.l    a0,d2
  209.     moveq    #-1,d3
  210. .loop
  211.     addq.l    #1,d3
  212.     tst.b    (a0)+
  213.     bne.s    .loop
  214.     CALLDOS    Write
  215.     rts
  216.  
  217. wait_key
  218. ;**** wait for key in raw window *****
  219.     move.l    rawwindow(pc),d1
  220.     lea    press_key(pc),a0
  221.     bsr    print
  222.     move.l    rawwindow(pc),d1
  223.     lea    buffer(pc),a0
  224.     move.l    a0,d2
  225.     moveq    #1,d3
  226.     CALLDOS    Read
  227.     rts
  228.  
  229.  
  230.  
  231. GetDrive
  232. ;***************************************************************************
  233. ;                                                                          *
  234. ; Drive disable/enable, (C) Dr. Maybe, Huissen 1990                        *
  235. ; This routine disables a drive from being used by AmigaDOS, for example   *
  236. ; if you want to format a disk, or install a bootintro on it.              *
  237. ; In WorkBench this will result in a "BUSY" icon.                          *
  238. ; Afterwards drive must be returned to system.                             *
  239. ;                                                                          *
  240. ; usage:                                                                   *
  241. ;       error = GetDrive( drive_name, action )                             *
  242. ;        d0                  a0         d0                                 *
  243. ;                                                                          *
  244. ;       drive_name = NULL-terminated string to drive name (e.g. 'DF1:',0)  *
  245. ;       action     = 1 to get drive for own use                            *
  246. ;                    0 to return drive to system                           *
  247. ;                                                                          *
  248. ;       error      = 0 if OK                                               *
  249. ;                    103 if not enough memory                              *
  250. ;                    218 if drive not mounted                              *
  251. ;                    100 if dos error                                      *
  252. ;                    126 if disable failed                                 *
  253. ;                                                                          *
  254. ;***************************************************************************
  255.  
  256.     move.l    d0,d2            ;d2 = action
  257.     move.l    a0,a3            ;a3 = drive name
  258.  
  259.  
  260. ;===========================================================================
  261. ; Allocate memory for StandardPacket structure                             #
  262. ;===========================================================================
  263.  
  264.     moveq    #sp_SIZEOF,d0
  265.     move.l    #MEMF_CLEAR+MEMF_PUBLIC,d1
  266.     CALLEXEC AllocMem
  267.     bne.s    .cnt3
  268.  
  269.     moveq    #103,d0
  270.     rts
  271. .cnt3
  272.     move.l    d0,a2            ;a2 = StandardPacket
  273.  
  274.  
  275. ;===========================================================================
  276. ; Initialize a StandardPacket to send to process that controls the drive   #
  277. ;===========================================================================
  278.  
  279.     lea    sp_Pkt(a2),a0
  280.     move.l    a0,sp_Msg+MN+LN_NAME(a2);message node name = DOS packet
  281.     move.l    a2,sp_Pkt+dp_Link(a2)    ;pointer to exec message
  282.  
  283.     sub.l    a1,a1            ;own task (process)
  284.     CALL    FindTask
  285.     move.l    d0,a1
  286.     lea    pr_MsgPort(a1),a0    ;own task message port is
  287.     move.l    a0,d4
  288.     move.l    a0,sp_Pkt+dp_Port(a2)    ;=> ReplyPort for packet
  289.  
  290.     moveq    #ACTION_INHIBIT,d0    ;dospacket type/action (=INHIBIT)
  291.     move.l    d0,sp_Pkt+dp_Type(a2)
  292.                     ;=========================
  293.     move.l    d2,sp_Pkt+dp_Arg1(a2)    ; dospacket Arg          #
  294.                     ; 1 = disable drive task #
  295.                     ; 0 = enable drive task  #
  296.                     ;=========================
  297.  
  298.  
  299. ;===========================================================================
  300. ; Get MessagePort of process that controls the drive (trackdisk?)          #
  301. ;===========================================================================
  302.  
  303.     move.l    a3,d1            ;DrivePort = DeviceProc(drivename)
  304.     CALLDOS    DeviceProc
  305.     bne.s    .cnt1
  306.     move.l    #218,d2
  307.     bra.s    .end
  308. .cnt1
  309.  
  310.  
  311. ;===========================================================================
  312. ; Now send the StandardPacket to the drive process                         #
  313. ;===========================================================================
  314.  
  315.     move.l    d0,a0            ;MessagePort of drive task
  316.     move.l    a2,a1            ;packet (message)
  317.     CALLEXEC PutMsg
  318.  
  319.  
  320. ;===========================================================================
  321. ; Check result & exit                                                      #
  322. ;===========================================================================
  323.  
  324.     moveq    #0,d2            ;error code
  325.  
  326. ;WAIT UNTIL WE GET A MESSAGE BACK
  327.     move.l    d4,a0            ;our task's reply port
  328.     CALL    WaitPort
  329.     cmp.l    d0,a2            ;is it the right reply message?
  330.     beq.s    .cnt2
  331.  
  332.     moveq    #100,d2            ;dos failure/wrong reply message
  333. .cnt2
  334.  
  335. ;REMOVE PACKET FROM LIST
  336.     move.l    a2,a1            ;remove packet from list
  337.     CALLEXEC Remove
  338.     tst.l    sp_Pkt+dp_Res1(a2)    ;check result
  339.     bne.s    .end
  340.  
  341.     moveq    #126,d0
  342.  
  343. .end
  344. ;EXIT WITH ERROR IN D0
  345.     move.l    a2,a1            ;free memory for StandardPacket
  346.     moveq    #sp_SIZEOF,d0
  347.     CALLEXEC FreeMem
  348.  
  349.     move.l    d2,d0
  350.     rts
  351.  
  352. ;===========================================================================
  353.  
  354. _DOSBase    dc.l    0
  355. rawwindow    dc.l    0
  356. buffer        dc.l    0
  357.  
  358. _DOSName    dc.b    "dos.library",0
  359. rawwindowname    dc.b    "RAW:120/78/400/100/GetDrive",0
  360. drivename    dc.b    "DF0:",0
  361.  
  362. not_mounted    dc.b    10," Drive not mounted!",10,10,0
  363. doserror    dc.b    10," DOS Error. Packet reply failure!",10,10,0
  364. drive_in_use    dc.b    10," Can't get drive (in use?)",10,10,0
  365. drive_disabled    dc.b    10," Drive DF0: disabled.",10,10,0
  366. press_key    dc.b    " Press any key to return...",10,10
  367.  
  368.